package com.hqd.jjvm.classformat.attributeinfo;

import com.hqd.jjvm.classformat.ClassFile;
import com.hqd.jjvm.util.HexStrTransformUtil;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;

@Getter
@NoArgsConstructor
public class LocalVariableTypeTable extends AttributeInfo {
	private Integer localVariableTypeLength;
	private List<LocalVariableType> localVariableTypeList;

	public LocalVariableTypeTable(Integer attributeNameIndex, Integer attributeLength, Integer localVariableTypeLength, List<LocalVariableType> localVariableTypeList) {
		super(attributeNameIndex, attributeLength);
		this.localVariableTypeLength = localVariableTypeLength;
		this.localVariableTypeList = localVariableTypeList;
	}

	@Getter
	class LocalVariableType {
		private Integer startPc;
		private Integer length;
		private Integer nameIndex;
		private Integer signatureIndex;
		private Integer index;

		public LocalVariableType(Integer startPc, Integer length, Integer nameIndex, Integer signatureIndex, Integer index) {
			this.startPc = startPc;
			this.length = length;
			this.nameIndex = nameIndex;
			this.signatureIndex = signatureIndex;
			this.index = index;
		}
	}

	@Override
	protected LocalVariableTypeTable newAttributeInfo(Integer attributeNameIndex, Integer attributeLength, ClassFile classFile) {
		this.localVariableTypeLength = HexStrTransformUtil.parseHexToInt(classFile.readU2());
		List<LocalVariableType> localVariableTypes = new ArrayList<>(localVariableTypeLength);
		for (int i = 0; i < localVariableTypeLength; i++) {
			int startPc = HexStrTransformUtil.parseHexToInt(classFile.readU2());
			int length = HexStrTransformUtil.parseHexToInt(classFile.readU2());
			int nameIndex = HexStrTransformUtil.parseHexToInt(classFile.readU2());
			int sIndex = HexStrTransformUtil.parseHexToInt(classFile.readU2());
			int index = HexStrTransformUtil.parseHexToInt(classFile.readU2());
			localVariableTypes.add(new LocalVariableType(startPc, length, nameIndex, sIndex, index));
		}
		this.localVariableTypeList = localVariableTypes;
		return this;
	}
}
